static void monitor_mk_pagetable(struct exec_domain *ed)
{
unsigned long mpfn;
- l2_pgentry_t *mpl2e;
+ l2_pgentry_t *mpl2e, *phys_table;
struct pfn_info *mpfn_info;
struct domain *d = ed->domain;
mk_l2_pgentry((__pa(d->arch.mm_perdomain_pt) & PAGE_MASK)
| __PAGE_HYPERVISOR);
+ phys_table = (l2_pgentry_t *) map_domain_mem(pagetable_val(
+ ed->arch.phys_table));
+ memcpy(d->arch.mm_perdomain_pt, phys_table,
+ ENTRIES_PER_L2_PAGETABLE * sizeof(l2_pgentry_t));
+
+ unmap_domain_mem(phys_table);
unmap_domain_mem(mpl2e);
}
phys_basetab = c->pt_base;
d->arch.pagetable = mk_pagetable(phys_basetab);
+ d->arch.phys_table = d->arch.pagetable;
if ( !get_page_and_type(&frame_table[phys_basetab>>PAGE_SHIFT], d->domain,
PGT_base_page_table) )
return -EINVAL;
#ifdef CONFIG_VMX
static void vmx_domain_relinquish_memory(struct exec_domain *ed)
{
- struct domain *d = ed->domain;
-
/*
* Free VMCS
*/
ed->arch.arch_vmx.vmcs = 0;
monitor_rm_pagetable(ed);
-
- if (ed == d->exec_domain[0]) {
- int i;
- unsigned long pfn;
-
- for (i = 0; i < ENTRIES_PER_L1_PAGETABLE; i++) {
- unsigned long l1e;
-
- l1e = l1_pgentry_val(d->arch.mm_perdomain_pt[i]);
- if (l1e & _PAGE_PRESENT) {
- pfn = l1e >> PAGE_SHIFT;
- free_domheap_page(&frame_table[pfn]);
- }
- }
- }
-
}
#endif
}
if (gpfn == 0) {
- VMX_DBG_LOG(DBG_LEVEL_1, "No shared Page ?\n");
+ printk("No shared Page ?\n");
+ unmap_domain_mem(p);
return -1;
}
unmap_domain_mem(p);
mpfn = phys_to_machine_mapping(gpfn);
p = map_domain_mem(mpfn << PAGE_SHIFT);
+ ASSERT(p != NULL);
d->arch.arch_vmx.vmx_platform.shared_page_va = (unsigned long) p;
return 0;
}
-
-/*
- * Add <guest pfn, machine pfn> mapping to per-domain mapping. Full
- * virtualization does not need per-domain mapping.
- */
-static int add_mapping_perdomain(struct exec_domain *d, unsigned long gpfn,
- unsigned long mpfn)
-{
- struct pfn_info *page;
- unsigned long pfn = 0;
-
- /*
- * We support up to 4GB memory for a guest at this point
- */
- if (gpfn > ENTRIES_PER_L2_PAGETABLE * ENTRIES_PER_L1_PAGETABLE)
- return -1;
-
- if (!(l1_pgentry_val(d->domain->arch.mm_perdomain_pt[
- gpfn >> (L2_PAGETABLE_SHIFT - L1_PAGETABLE_SHIFT)]) & _PAGE_PRESENT))
- {
- page = (struct pfn_info *) alloc_domheap_page(NULL);
- if (!page) {
- return -1;
- }
-
- pfn = (unsigned long) (page - frame_table);
- d->domain->arch.mm_perdomain_pt[gpfn >> (L2_PAGETABLE_SHIFT - L1_PAGETABLE_SHIFT)] =
- mk_l1_pgentry((pfn << PAGE_SHIFT) | __PAGE_HYPERVISOR);
- }
- __phys_to_machine_mapping[gpfn] = mpfn;
-
- return 0;
-}
-
void vmx_do_launch(struct exec_domain *ed)
{
/* Update CR3, GDT, LDT, TR */
d->arch.min_pfn = min(d->arch.min_pfn, pfn);
d->arch.max_pfn = max(d->arch.max_pfn, pfn);
list_ent = frame_table[pfn].list.next;
- add_mapping_perdomain(ed, i, pfn);
}
spin_unlock(&d->page_alloc_lock);
pagetable_t pagetable;
pagetable_t monitor_table;
+ pagetable_t phys_table; /* 1:1 pagetable */
pagetable_t shadow_table;
l2_pgentry_t *vpagetable; /* virtual address of pagetable */
l2_pgentry_t *shadow_vtable; /* virtual address of shadow_table */
#include <asm/desc.h>
#include <asm/flushtlb.h>
#include <asm/io.h>
+#include <asm/uaccess.h>
#include <public/xen.h>
/* Returns the machine physical */
static inline unsigned long phys_to_machine_mapping(unsigned long pfn)
{
- return __phys_to_machine_mapping[pfn];
+ unsigned long mfn;
+ l1_pgentry_t pte;
+
+ if (__get_user(l1_pgentry_val(pte), (__phys_to_machine_mapping + pfn))) {
+ return 0;
+ }
+
+ mfn = l1_pgentry_to_phys(pte) >> PAGE_SHIFT;
+ return mfn;
}
#define set_machinetophys(_mfn, _pfn) machine_to_phys_mapping[(_mfn)] = (_pfn)
#include <xen/errno.h>
#include <xen/prefetch.h>
#include <xen/string.h>
-#include <xen/sched.h>
#define __user
#include <xen/config.h>
#include <xen/compiler.h>
#include <xen/errno.h>
-#include <xen/sched.h>
#include <xen/prefetch.h>
#include <asm/page.h>